<template>
    <slot></slot>
</template>
<script lang="ts">
import { defineComponent, PropType, provide } from 'vue'
import Evt from 'ph-evt'
import * as Vs from './validators'
import Vq from './queue'
import { PhValidationQueue, PhValidatorTask } from './index.type'

export default defineComponent({
    props:{
        validators:{
            type:Object as PropType<Record<string,PhValidatorTask >>,
            default:()=>({})
        }
    },
    setup(props) {
        const vevt = new Evt() 
        const fields:Array<()=>Promise<unknown>> = []
        const vqueues:Record<string,PhValidationQueue> = {}
        const Vs1 = {
            ...Vs,...props.validators
        } as Record<string,PhValidatorTask>

        const getVq = (vs:Array<string>)=>{
            const vkey = vs.join("")
            let vq = vqueues[vkey]
            if(vq)return vq
            vq = Vq.create()
            vs.forEach(key=>{
                if(!key)return
                const raws = key.split("|"),
                    k = raws[0],
                    args = raws[1];
                const task = Vs1[k]
                // if(k==='length')console.log(args)
                task&&vq.use(task,k==="regexp"?[key.substr(k.length+1)]:args?.split("-"))
            })
            vqueues[vkey]=  vq
            return vq
        }
        const validate = (value:unknown, vs:Array<string>)=>{
            if(!vs||vs.length==0)return Promise.resolve(true)
            return getVq(vs).run(value)
        }
        const registerField = (vf:()=>Promise<unknown>)=>{
            fields.push(vf)
        }
        const validateAll = ()=>{
            return Promise.all(fields.map(vf=>vf()))
        }
        provide("vevt",vevt)
        provide("registerField",registerField)
        provide("validateAll",validateAll)
        provide("phValidate",validate)
        provide("phValidation",true)
        
    },
})
</script>
